﻿using Adnc.Application.Shared.Services;
using Adnc.Infra.Helper;
using Adnc.Infra.IRepositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WYT.Pro.Application.Contracts.Dtos.Logistics;
using WYT.Pro.Application.Contracts.Services;
using WYT.Pro.Repository.Entities;

namespace WYT.Pro.Application.Services
{
    /// <summary>
    /// 运费服务
    /// </summary>
    public class LogisticsAppService : AbstractAppService, ILogisticsAppService
    {
        private readonly IEfRepository<LogisticsPrice> _logisticsPriceRepository;
        private readonly IEfRepository<Logistics> _logisticsRepository;
        public LogisticsAppService(
            IEfRepository<LogisticsPrice> logisticsPriceRepository
            , IEfRepository<Logistics> logisticsRepository
            )
        {
            _logisticsPriceRepository = logisticsPriceRepository;
            _logisticsRepository = logisticsRepository; 
        }

        /// <summary>
        /// 邮费计算
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<AppSrvResult<PostageDto>> PostageCalculation(PostageCalculationDto input)
        {
            var postage = new PostageDto();
            var ids = input.ProductInfors.Select(c => c.Id).ToArray();
            string sql = $@"SELECT
	                            GoodsId,
	                            FirstCost,
	                            FirstPiece,
	                            ContinuationPiece,
	                            ContinuationCost,
	                            FreeShippingCost,
	                            FreeShippingCount 
                            FROM
	                            (
	                            SELECT
		                            ROW_NUMBER() OVER ( PARTITION BY t1.GoodsId ORDER BY t1.CODE DESC ) AS rn,
		                            t1.* 
	                            FROM
		                            (
		                            SELECT
			                            pg.Id AS GoodsId,
			                            lp.* 
		                            FROM
                                        pro_Goods pg 
                                        JOIN pro_Logistics pl ON pg.LogisticsID = pl.Id
			                            JOIN pro_LogisticsPrice lp ON pl.Id = lp.LogisticsID 
		                            WHERE
                                        pl.State = 0    
			                            And pg.Id IN @ids 
			                            AND lp.CODE = SUBSTRING(@AddrCode,1,LENGTH( lp.CODE )) 
		                            ) t1 
	                            ) t2 
                            WHERE
	                            t2.rn = 1";

            var ProductPostagePrices = (await _logisticsRepository.QueryAsync<ProductLogisticsDto>(sql,new { ids, input.AddrCode})).ToList();
            foreach (var product in input.ProductInfors)
            {
                Decimal price = 0;
                var postageprice = ProductPostagePrices.FirstOrDefault(c => c.GoodsId == product.Id);
                //如果没有找到运费信息，默认包邮
                if (postageprice == null)
                    continue;
                //判断是否满足购物件数包邮
                if (postageprice.FreeShippingCount.HasValue && product.Count >= postageprice.FreeShippingCount)
                    continue;

                //判断是否满足购物金额包邮
                if (postageprice.FreeShippingCost.HasValue && postageprice.FreeShippingCost <= product.Amount)
                    continue;

                price = postageprice.FirstCost;
                //续件费用。 续件费用 = （数量 - 首件件数 + 续件件数 - 1)/续件件数 * 费用 =  Math,Ceiling((数量-首件件数)/续件件数) * 费用
                if (postageprice.FirstPiece < product.Count)
                    price += ((product.Count - postageprice.FirstPiece + postageprice.ContinuationPiece - 1) / postageprice.ContinuationPiece) * postageprice.ContinuationCost;

                postage.TotalPostage += price;
            }

            return postage;
        }
    }
}
